package cn.iocoder.boot.service.impl.supplier;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import cn.iocoder.boot.entity.ComponentPrice;
import cn.iocoder.boot.entity.ComponentStock;
import cn.iocoder.boot.enums.SupplierCodeEnum;
import cn.iocoder.boot.service.CallLimitService;
import cn.iocoder.boot.service.ComponentPriceService;
import cn.iocoder.boot.service.ComponentStockService;
import cn.iocoder.boot.service.HttpRequestLogService;
import cn.iocoder.boot.service.impl.SalePriceConfigServiceImpl;
import cn.iocoder.boot.utils.MessageUtil;
import cn.iocoder.boot.vo.AttrVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static cn.iocoder.boot.enums.SupplierCodeEnum.ELEMENT;

@Service
@DS("master")
@Slf4j
public class ElementServiceImpl {

    private static final String API_URL = "http://192.168.10.92:8010/element.ashx?cmd=enquiryex";
    private static final BigDecimal TAX_RATE = new BigDecimal("1.13");
    private static final BigDecimal PRICE_ADJUSTMENT_RATE = new BigDecimal("0.9");
    private static final int SCALE = 4;

    @Resource
    private ComponentStockService componentStockService;
    @Resource
    private SalePriceConfigServiceImpl salePriceConfigService;
    @Resource
    private ComponentPriceService componentPriceService;
    @Resource
    private CallLimitService callLimitService;
    @Resource
    private HttpRequestLogService httpRequestLogService;

    public List<ComponentPrice> queryOne(String model, Map<String, BigDecimal> componentSupplierMap) {
        // 定义最大重试次数
        int maxRetries = 2;
        // 当前重试次数
        int retryCount = 0;

        while (retryCount <= maxRetries) {
            try {
                callLimitService.supplierLimitCall(ELEMENT.getCode());

                String encodedModel = URLEncoder.encode(model.replace("＋", "+"), StandardCharsets.UTF_8);
                String postData = "code=" + encodedModel;

                // 使用Hutool的HttpRequest发送POST请求
                try (HttpResponse response = HttpRequest.post(API_URL)
                        .body(postData)
                        .timeout(8000) // 设置超时时间
                        .execute()) {
                    httpRequestLogService.saveHttpRequestLog(API_URL, "Element_queryOne", model, response.body(), response.getStatus());
                    String responseBody = response.body();
                    log.info("{} Element queryOne API response: {}", model, responseBody);

                    return processResponse(responseBody, componentSupplierMap, model);
                }
            } catch (Exception e) {
                log.error("Error occurred while querying Element API for model: {} (retry count: {})", model, retryCount, e);

                // 检查是否是需要重试的异常
                if (e.getMessage() != null &&
                        (e.getMessage().contains("Connect timed out") || e.getMessage().contains("Connection timed out") ||
                                e.getMessage().contains("Read timed out")) &&
                        retryCount < maxRetries) {

                    retryCount++;
                    log.info("Retrying query for model: {} (retry {}/{})", model, retryCount, maxRetries);
                    try {
                        // 重试前短暂延迟，避免频繁请求
                        Thread.sleep(1000);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break; // 线程被中断，停止重试
                    }
                } else {
                    // 不需要重试的异常或达到最大重试次数，执行最终异常处理
                    MessageUtil.sentMessage("26827", "易洛盟查询型号异常" + e.getMessage(), "易洛盟查询型号异常");
                    break;
                }
            }
        }

        return new ArrayList<>();
    }

    public void query(List<String> models, Map<String, BigDecimal> componentSupplierMap) {
        for (String model : models) {
            queryOne(model, componentSupplierMap);
        }
    }

    /**
     * 处理API响应数据
     */
    private List<ComponentPrice> processResponse(String responseBody, Map<String, BigDecimal> componentSupplierMap, String model) {
        if (responseBody == null || responseBody.isEmpty()) {
            log.warn("Empty response from Element API");
            return new ArrayList<>();
        }

        JSONObject jsonResponse = JSON.parseObject(responseBody);
        int code = jsonResponse.getIntValue("code");
        List<ComponentPrice> componentPriceList = new ArrayList<>();
        if (code == 0) {
            JSONArray dataArray = jsonResponse.getJSONArray("products");
            if (dataArray == null || dataArray.isEmpty()) {
                log.info("No products found in Element API response");
                return new ArrayList<>();
            }

            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject item = dataArray.getJSONObject(i);
                ComponentPrice componentPrice = processProductItem(item, componentSupplierMap, model);
                componentPriceList.add(componentPrice);
            }
        } else {
            log.error("Element API returned error code: {}", code);
        }
        return componentPriceList;
    }

    /**
     * 处理单个产品数据
     */
    private ComponentPrice processProductItem(JSONObject item, Map<String, BigDecimal> componentSupplierMap, String model) {
        // 创建ComponentStock对象
        ComponentStock stock = createComponentStock(item, model);

        // 处理价格数据
        JSONArray prices = item.getJSONArray("prices");
        if (prices == null || prices.isEmpty()) {
            log.warn("No prices found for product: {}", item.getString("sku"));
            return null;
        }

        List<JSONObject> convertedPrices = convertPrices(prices);

        JSONArray stdPrices = item.getJSONArray("std_prices");
        List<JSONObject> adjustedPrices = convertPrices(stdPrices);

        componentStockService.saveComponentStockOfUniqueKey(stock);
        ComponentPrice componentPrice =
                saveComponentPrice(stock.getUniqueId(), item, adjustedPrices, convertedPrices, componentSupplierMap);
        componentPrice.setStockInfo(stock);
        return componentPrice;

    }

    /**
     * 创建ComponentStock对象
     */
    private ComponentStock createComponentStock(JSONObject item, String model) {
        ComponentStock stock = new ComponentStock();
        stock.setModel(item.getString("translatedManufacturerPartNumber"));
        stock.setPartnumber(item.getString("sku"));
        stock.setBrand(item.getString("brandName"));
        stock.setSpecifications(item.getString("displayName"));
        stock.setKeyword(model);
        String attributes = item.getString("attributes");
        if (StringUtils.isNotBlank(attributes)) {
            List<AttrVO> attrVOList = JSONUtil.toList(attributes, AttrVO.class);
            attrVOList.stream()
                    .filter(attr -> "usEccn".equals(attr.getAttributeLabel()))
                    .findFirst()
                    .ifPresent(attr -> stock.setExportControlClassificationNumber(attr.getAttributeValue()));
        }
        stock.setMinNum(StringUtils.isEmpty(item.getString("translatedMinimumOrderQuality")) ? null :
                Integer.valueOf(item.getString("translatedMinimumOrderQuality")));
        stock.setStockType(1);
        stock.setSupplierCode(ELEMENT.getCode());
        stock.setUniqueId(SupplierCodeEnum.ELEMENT.getCode() + "_" + item.getString("sku"));
        return stock;
    }

    /**
     * 转换价格数据（乘以税率）
     */
    private List<JSONObject> convertPrices(JSONArray prices) {
        List<JSONObject> convertedPrices = new ArrayList<>();

        for (int j = 0; j < prices.size(); j++) {
            JSONObject price = prices.getJSONObject(j);
            if (price == null) continue;

            BigDecimal originalCost = new BigDecimal(price.getString("cost"));
            BigDecimal adjustedCost = originalCost.multiply(TAX_RATE)
                    .setScale(SCALE, RoundingMode.HALF_UP);

            JSONObject convertedPrice = new JSONObject();
            convertedPrice.put("Price", adjustedCost);
            convertedPrice.put("Currency", "RMB");
            convertedPrice.put("Quantity", price.getInteger("from"));

            convertedPrices.add(convertedPrice);
        }

        return convertedPrices;
    }

    /**
     * 调整价格数据（除以调整率）
     */
    private List<JSONObject> adjustPrices(List<JSONObject> convertedPrices) {
        List<JSONObject> adjustedPrices = new ArrayList<>();

        for (JSONObject originalPrice : convertedPrices) {
            BigDecimal adjustedCost = new BigDecimal(originalPrice.getString("Price"))
                    .divide(PRICE_ADJUSTMENT_RATE, SCALE, RoundingMode.HALF_UP);

            JSONObject adjustedPrice = new JSONObject();
            adjustedPrice.put("Price", adjustedCost);
            adjustedPrice.put("Currency", originalPrice.getString("Currency"));
            adjustedPrice.put("Quantity", originalPrice.getInteger("Quantity"));

            adjustedPrices.add(adjustedPrice);
        }

        return adjustedPrices;
    }

    /**
     * 保存组件价格信息
     */
    private ComponentPrice saveComponentPrice(String uniqueId, JSONObject item, List<JSONObject> costPrice,
                                              List<JSONObject> price, Map<String, BigDecimal> componentSupplierMap) {
        String saleJson = salePriceConfigService.getSaleJson(
                costPrice.toString(),
                item.getString("translatedManufacturerPartNumber"),
                "RMB"
        );

        Long stockLevel = item.getJSONObject("stock") != null
                ? Long.valueOf(item.getJSONObject("stock").getInteger("level"))
                : 0L;

        ComponentPrice componentPrice = new ComponentPrice(
                uniqueId,
                price.toString(),
                stockLevel,
                null,
                item.getString("unitOfMeasure"),
                "RMB",
                item.getString("translatedManufacturerPartNumber"),
                costPrice.toString(),
                saleJson,
                componentSupplierMap.getOrDefault(ELEMENT.getCode(), BigDecimal.valueOf(2))
        );

        componentPriceService.createComponentPriceOfUniqueKey(componentPrice);
        return componentPrice;
    }
}
